#include <array>
#include <vector>

//#include <QMessageBox>
#include<debugx>
#include <iostream>
#include <memory>

namespace localVariable {

inline int index(bool reset=false){ static int i=0; if(reset)i=0; return i++;}

using namespace std;
class MyDemo {
public:

    int id=index();
    int j=0;

    MyDemo(): data_(nullptr), size_(0) {
        dinfo("\t default constructor  id=%d ",id);
    }

    explicit MyDemo(size_t size)
        : data_(new char[size]), size_(size) {
        dinfo("\t parameter constructor  id=%d ",id);
    }
    MyDemo(const MyDemo& other) {

        data_ = new char[other.size_];
        memcpy(data_, other.data_, other.size_);
        size_ = other.size_;
        j=other.j;
        dinfo("\t copy constructor  id=%d  other.id=%d",id,other.id);
    }

    MyDemo& operator=(const MyDemo& other) {

        if (this == &other) {
            return *this;
        }
        delete[] data_;
        data_ = new char[other.size_];
        memcpy(data_, other.data_, other.size_);
        size_ = other.size_;
        j=other.j;
        dinfo("\t copy assignment operator  id=%d  other.id=%d",id,other.id);
        return *this;
    }

    ~MyDemo() { dinfo("\t destructor id=%d, j=%d ",id,j); delete[] data_;}
#define min(a,b) (a)<(b)?(a):(b)

    void set(size_t offset, size_t len, const void* src) {
        len = min(len, size_ - offset);
        memcpy(data_ + offset, src, len);
    }
private:
    char* data_;
    size_t size_;
};

MyDemo myfun(MyDemo m)
{
    m.j=200+m.id;
    return m;
}
MyDemo myfun()
{
    MyDemo m;
    m.j=m.id;
    return m;
}
MyDemo myfun1()
{
    auto m=myfun();
    return m;
}
MyDemo &myRef()
{
    MyDemo m;//局部变量，只能返回它的拷贝，不能返回引用。
    m.j=m.id;
    return m;
}
const MyDemo &myRefC()
{
    MyDemo m;//局部变量，只能返回它的拷贝，不能返回引用。
    m.j=m.id;
    return m;
}
MyDemo &myRefA(MyDemo a)//值传递
{
    a.j=100;
    return a;
}
MyDemo &myRefB(MyDemo &a)//引用传递
{
    a.j=100;
    return a;
}
MyDemo createBlob(const char* str) {
    size_t len = strlen(str);
    MyDemo blob(len);
    blob.set(0, len, str);
    return blob;
}

vector<MyDemo> vecFun()
{
    vector<MyDemo> vec;
    MyDemo d1;
    MyDemo d2;
    MyDemo d3;
    MyDemo d4;
    MyDemo d5;
    MyDemo d6;

    d1.j=10;
    d2.j=20;
    d3.j=30;
    d4.j=40;
    d5.j=50;
    d6.j=60;

    vec.push_back(d1);
    vec.push_back(d2);
    dinfo("push end \n");

    vec.emplace(vec.begin(), d3);
    vec.emplace(vec.end(), d4);
    dinfo("emplace end \n");

    vec.insert(vec.begin(), d5);
    vec.insert(vec.end(), d6);
    dinfo("insert end \n");

    return vec;
}

void demoMain() {

    MyDemo m;
    dinfo("id= %d",m.id);//0
    myfun(m);//传参复制一次，返回值复制一次
    dinfo("\n值传递结束");
    //值传递结束

    auto m1=myfun1();
    dinfo("m1  id= %d",m1.id);//1

    MyDemo blob; //2
   dinfo("\t current MyDemo id=%d ",blob.id);

    dinfo1 << "Start assigning value..." ;
    blob = createBlob("A very very very long string representing serialized data");//3
    dinfo1 << "End assigning value" ;


}

void demo2()
{
    index(true);//清0
    dinfo("\n\t vector begin");
    auto vec=vecFun();//4,5    vec 6,7  第二个push_back会产生一个8

}
}
int main() {

    localVariable::demoMain();
    localVariable::demo2();
    dinfo("test function end!");
    return 0;
}
